﻿using CLROBS;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;

namespace DesertKharonIrcPlugin
{
    public class DesertKharonIrcImageSource : AbstractImageSource, IDisposable
    {
        private Object _lock = new Object();

        private Renderer _renderer;

        private IrcManager _ircManager;
        private XElement _config;
        private DesertKharonIrcPluginSettings _settings;

        // Init
        public DesertKharonIrcImageSource(XElement data)
        {
            _config = data;
            _settings = new DesertKharonIrcPluginSettings(data);

            UpdateSettings();
        }

        public override void UpdateSettings()
        {
            Size.X = (UInt32)120;
            Size.Y = (UInt32)120;

            lock (_lock)
            {
                _renderer = new Renderer(GS, _settings);
            }

            RestartIrcListener();
        }

        // Incomming Message
        private void MessageReceived(object sender, IrcManagerMessageReceivedEventArgs e)
        {
            IrcManagerMessage message = new IrcManagerMessage()
            {
                Source = e.Source,
                NickName = e.NickName,
                Message = e.Message,
                ReceiveDate = DateTime.Now,
                UserColor = e.Color
            };

            lock (_lock)
            {
                if (_renderer != null)
                    _renderer.AddMessage(message);
            }
        }

        // Clear chat for user
        private void ClearMessagesForNick(object sender, IrcManagerMessageReceivedEventArgs e)
        {
            lock (_lock)
            {
                if (_renderer != null)
                    _renderer.ClearMessagesFromNick(e.NickName);
            }
        }

        // Update
        public override void Tick(float fSeconds)
        {
            base.Tick(fSeconds);

            lock (_lock)
            {
                if (_renderer != null)
                    _renderer.Update(fSeconds);
            }
        }

        // Draw
        public override void Render(float x, float y, float width, float height)
        {
            lock (_lock)
            {
                if (_renderer != null)
                {
                    int secureWidth = width < 16f ? 16 : (int)width;
                    int secureHeight = height < 16f ? 16 : (int)height;

                    _renderer.Draw(secureWidth, secureHeight);

                    GS.DrawSprite(_renderer.Texture, 0xFFFFFFFF, x, y, x + width, y + height);
                }
            }
        }

        // IRC
        private void RestartIrcListener()
        {
            StopIrcManager();
            StartIrcManager();
        }

        private void IrcConnectionFailed(object sender, EventArgs e)
        {
            MessageBox.Show("IRC connection failed.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        private void IrcConnectionEstablished(object sender, EventArgs e)
        {
        }

        private void StartIrcManager()
        {
            IrcManagerSettings ircManagerSettings = new IrcManagerSettings()
            {
                LoginPreset = _settings.LoginPreset,
                HostName = _settings.IrcServer,
                Port = _settings.IrcServerPort,
                UserName = _settings.IrcServerNickName,
                NickName = _settings.IrcServerNickName,
                RealName = _settings.IrcServerNickName,
                Password = _settings.IrcServerPassword,
                ChannelName = _settings.IrcServerChannelName,
                BroadcasterNickName = _settings.BroadcasterNickName,
                ShowJoinsParts = _settings.ShowJoinsParts
            };

            lock (_lock)
            {
                _ircManager = new IrcManager(ircManagerSettings);

                _ircManager.MessageReceived += MessageReceived;
                _ircManager.ClearMessagesForNick += ClearMessagesForNick;
                _ircManager.ConnectionEstablished += IrcConnectionEstablished;
                _ircManager.ConnectionFailed += IrcConnectionFailed;

                _ircManager.ModeratorList = _settings.ModeratorList;
                _ircManager.FriendList = _settings.FriendList;
                _ircManager.FoeList = _settings.FoeList;
                _ircManager.IgnoreList = _settings.IgnoreList;

                

                _ircManager.Start();
            }
        }

        private void StopIrcManager()
        {
            lock (_lock)
            {
                if (_ircManager != null)
                {
                    _ircManager.MessageReceived -= MessageReceived;
                    _ircManager.ClearMessagesForNick -= ClearMessagesForNick;
                    _ircManager.ConnectionEstablished -= IrcConnectionEstablished;
                    _ircManager.ConnectionFailed -= IrcConnectionFailed;
                    _ircManager.Stop();

                    _ircManager = null;
                }
            }
        }

        public void Dispose()
        {
            StopIrcManager();
            
            if (_renderer != null)
            {
                _renderer.Dispose();
                _renderer = null;
            }
        }
    }
}
